<?php

namespace App\Http\Controllers\V1\API;

use App\Models\V1\AdminUser;
use App\Models\V1\Custodians;
use App\Models\V1\NewStudent;
use App\Models\V1\NewArrival;
use App\Models\V1\OAuthClients;
use App\Models\V1\WeChatLogin;
use GuzzleHttp\Client;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Auth;
use Log;
use Validator;
use App\Http\Controllers\V1\API\BaseController;

include_once 'wxBizDataCrypt.php';

class UserInformationsController extends BaseController
{
    use AuthenticatesUsers;
//    protected $guard = 'api';

    protected $app_id = 'wx6397396df988f501';
    protected $app_secret = 'f767a74b8fa834acbdf55971e858cb81';

//    public function authenticate(Request $request)
//    {
//        $code = $request->get('userID');
//        $password = $request->get('password');
//        $credentials = [
//            'code'=>$code,
//            'password'=>$password,
//            'is_staff'=>false
//        ];
//        try {
//            // attempt to verify the credentials and create a token for the user
//            if (! $token = JWTAuth::attempt($credentials)) {
//                return response()->json(['error' => 'invalid_credentials'], 401);
//            }
//        } catch (JWTException $e) {
//            // something went wrong whilst attempting to encode the token
//            return response()->json(['error' => 'could_not_create_token'], 500);
//        }
//
//        // all good so return the token
//        return response()->json(compact('token'));
//    }


    /***
     * 验证用户登录
     * code  用户名
     * password 密码
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */

    public function login(Request $request) {
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );
        $code = $request->get('userID');
        $password = $request->get('password');
        $wc_data = $request->get('wcData');
        if (empty($code) || empty($password)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] ='参数不正确';
            return $this->sendResponse($result, $result['errorCode']);
        }
        
        //app普通登陆
        if (($wc_data == null)||(empty($wc_data))||(count($wc_data) == 0)) {
            $credentials = [
                'code'=>$code,
                'password'=>$password,
                'is_staff'=>false
            ];
            if ($this->guard('api')->attempt($credentials)) {
                $password_client = \Laravel\Passport\Client::query()->where('password_client',1)->latest()->first();
                $request->request->add([
                    'grant_type' => 'password',
                    'client_id' => $password_client->id,
                    'client_secret' => $password_client->secret,
                    'username' => $code,
                    'password' => $password,
                    'scope' => '',
                ]);
                $proxy = Request::create(
                    'oauth/token',
                    'POST'
                );
                $response = \Route::dispatch($proxy);
                if ($response) {
                    $response = json_decode($response->getContent());
                    $access_token = $response->access_token;
                    if (empty($access_token) || !isset($access_token)) {
                        $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                        $result['errorMsg'] =$response->error;
                    }else {
                        $data=[
                            'access_token'=>$access_token
                        ];
                        $result['errorCode'] = Response::HTTP_OK;
                        $result['errorMsg'] = Response::$statusTexts[Response::HTTP_OK];
                        $result['data'] = $data;
                    }
                }else {
                    $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                    $result['errorMsg'] = '获取token失败';
                }

            }else {
                $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                $result['errorMsg'] ='用户名或密码不正确';
            }
        }else{
            //微信登陆（根据thirdSession获取到sessionKey,根据sessionKey获取到unionID，关联）
            $encryptedData = $wc_data['encryptedData'];
            $iv = $wc_data['iv'];
            $third_session = $wc_data['thirdSession'];

            //根据$third_session取出session_key
            $session_key = $this->getSessionKey($third_session,$result);
            //返回数组说明$third_session 不存在，可能已过期
            if (is_array($session_key)) {
                $result = $session_key;
                return $this->sendResponse($result, $result['errorCode']);
            }
            $wxBizDataCrypt = new \WXBizDataCrypt($this->app_id, $session_key);
            $error_code = $wxBizDataCrypt->decryptData($encryptedData, $iv, $data);
            if ($error_code == 0) {
                $data = json_decode($data,true);
//                $union_id = $data['unionId'];
                $union_id = $data['openId'];
                $open_id = $data['openId'];
                Log::info('data ========',$data);
                //关联用户
                $rspObj = $this->relateUser($union_id,$open_id,$code);
                if ($rspObj) {
                    $user = AdminUser::where('code',$code)->first();
                    //start
                    //
                    //检测用户是否为当前学期下注册的学生用户
                    $yingxin = NewArrival::where('isOn',1)->first();
                    if(!empty($yingxin)){
                        $yingxin_code = $yingxin->code;
                    }else{
                        $yingxin_code = '';
                    }

                    $new_student = NewStudent::where('exam_code', $code)->first();
                    if(!empty($new_student)){
                        $student_arrival_code = $new_student->arrival_code;
                    }else{
                        $student_arrival_code = '';
                    }
                    //判断当前启动的迎新code和学生所属的code是否一致
                    if($yingxin_code != $student_arrival_code){

                        $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                        $result['errorMsg'] = '登录学生不在当前学期';
                        return $this->sendResponse($result, $result['errorCode']);
                    }
                    //
                    //end
//                    $token = JWTAuth::fromUser($user);
//                    $user = AdminUser::where('code',$code)->first();
                    else{
                        $token = $user->createToken($code)->accessToken;
                        $data=[
                            'access_token'=>$token
                        ];
                        $result['errorCode'] = Response::HTTP_OK;
                        $result['errorMsg'] = Response::$statusTexts[Response::HTTP_OK];
                        $result['data'] = $data;
                    }
                }else {
                    $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                    $result['errorMsg'] ='登录失败';
                }
            }else {
                $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                $result['errorMsg'] =$error_code;
            }
        }
        return $this->sendResponse($result, $result['errorCode']);
    }


    public function logout()
    {
        Auth::guard($this->guard)->logout();
        return response()->json(['status' => 'ok']);
    }

    /****
     * 获取用户详细信息
     * @param Request $request
     */
    public function userDetail(Request $request){
        $code = $request->get('userID');
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );

        if (empty($code) || !isset($code)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '参数不正确';
        }else{
            $student = $this->getStudentInfo($code);
            if (empty($student) || !isset($student)) {
                $result['errorCode'] = Response::HTTP_NOT_FOUND;
                $result['errorMsg'] = '用户不存在';
            }else {
                $data = $this->handleUserInformation($student);
                $result['errorCode'] = Response::HTTP_OK;
                $result['errorMsg'] = Response::$statusTexts[Response::HTTP_OK];
                $result['data'] = $data;
            }
        }
        return $this->sendResponse($result, $result['errorCode']);
    }

    /****
     * 更新新用户信息
     * @param Request $request
     */
    public function updateData(Request $request){
        $code = $request->get('userID');
        // 自定义返回格式
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
            'data' => array()
        );
        if ($request->method() === 'POST') {
            $student = $this->getStudentInfo($code);
            if (empty($student) || !isset($student)) {
                $result['errorCode'] = Response::HTTP_NOT_FOUND;
                $result['errorMsg'] = '用户不存在';
            }else {
                $rspObj = $this->handleUpdate($request);
                if ($rspObj) {
                    $student = $this->getStudentInfo($code);
                    $data = $this->handleUserInformation($student);
                    $result['errorCode'] = Response::HTTP_OK;
                    $result['errorMsg'] = '用户信息更新成功';
                    $result['data'] = $data;
                }else {
                    $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                    $result['errorMsg'] = '用户信息更新失败';
                }
            }
        }
        return $this->sendResponse($result, $result['errorCode']);
    }


    /***
     * 更新用户头像
     * @param Request $request
     */
    public function updateAvatar(Request $request) {
        $result = [
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
            'data' => [
                'picPath' => '',
            ],
        ];
        if ($request->method() === 'POST') {
            // 存储路径
            $storagePath = 'api/avatar/';
            $storagePath .= $request->input('userID');
            // 获取request中上传文件对象
            $image_file = $request->file('imageFile');
            if (empty($image_file) || !isset($image_file)) {
                $result = [
                    'errorCode' => Response::HTTP_NOT_FOUND,
                    'errorMsg' => '文件不存在',
                ];
                return $this->sendResponse($result, $result['errorCode']);
            }
            // 在指定目录保存图片（原图）
            $originPath = Storage::disk('public')->put($storagePath, $image_file);

            $result_path =  ('storage' . '/' . $originPath);
            // 更新数据库中头像路径
            $success = $this->handleUpdateAvatar( $request->input('userID'), $result_path);
            if ($success) {
                $result['errorCode'] = Response::HTTP_OK;
                $result['errorMsg'] = '头像更新成功';
                $result['data'] = [
//                        'src' => asset('storage' . '/' . $originPath),
                    'picPath' => $result_path,
                ];
            } else {
                $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                $result['errorMsg'] = '头像更新失败！';
            }
        }
        return $this->sendResponse($result, $result['errorCode']);
    }

    public function userLogout(Request $request) {
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );
        $code = $request->get('userID');
        if (empty($code) || !isset($code)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '参数不正确';
            return $this->sendResponse($result, $result['errorCode']);
        }
//        AccessTokenCreated::
//        event(new RevokeOldTokens());
        if ($rspObj) {
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] = '成功';
        }else {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '失败';
        }
        return $this->sendResponse($result, $result['errorCode']);
    }


    /****
     * 获取学生信息
     * @param $code
     */

    private function handleUserInformation($student){
        $dataUser['userID'] = isset($student['exam_code'])?$student['exam_code']:'';
        $dataUser['userName'] = isset($student['name'])?$student['name']:'';
        $dataUser['userAvatar'] = isset($student['avatar'])?$student['avatar']:'';
        $dataUser['cardNumber'] = isset($student['card_number'])?$student['card_number']:'';
        $dataUser['telephone'] = isset($student['mobile'])?$student['mobile']:'';
        $dataUser['height'] = isset($student['height'])?$student['height']:'';
        $dataUser['weight'] = isset($student['weight'])?$student['weight']:'';
        $dataUser['address'] = isset($student['address'])?$student['address']:'';
        $dataUser['physical'] = isset($student['physical_fitness'])?$student['physical_fitness']:'';
        $dataUser['psychological'] = isset($student['psychological_quality'])?$student['psychological_quality']:'';
        $history = $student['medical_history'];
        $record = array();
        if (empty($history) || !isset($history)) {
            $record['physical'] = '';
            $record['psychological'] = '';
        }else{
            $historyArr = explode('--',$history);
            if (count($historyArr) == 2){
                $record['physical'] = $historyArr[0];
                $record['psychological'] = $historyArr[1];
            }elseif (count($historyArr) == 1) {
                $record['physical'] = $historyArr[0];
                $record['psychological'] = '';
            }else {
                $record['physical'] = '';
                $record['psychological'] = '';
            }
        }
        $dataUser['record'] = $record;
        $dataUser['remark'] = isset($student['ill_remark'])?$student['ill_remark']:'';
        $custodians = $this->getStudentCustodians($student['exam_code']);
        $formatCustodian = array();
        foreach ($custodians as $item) {
            $custodian['title'] = isset($item['custodian_title'])?$item['custodian_title']:'';
            $custodian['name']= isset($item['custodian_name'])?$item['custodian_name']:'';
            $custodian['mobile'] = isset($item['custodian_mobile'])?$item['custodian_mobile']:'';
            array_push($formatCustodian,$custodian);
        }
        $dataUser['custodians'] = $formatCustodian;
        return $dataUser;
    }

    /****
     * 用户信息更新操作
     * @param Request $request
     * @return mixed
     */
    private function handleUpdate(Request $request) {
        $code = $request->get('userID');
        $telephone = $request->get('telephone');
        $address = $request->get('address');
        $height = $request->get('height');
        $weight = $request->get('weight');

        $physical = $request->get('physical');  //身体素质
        $psychological = $request->get('psychological');   //心理素质
        $record = $request->get('record');    //病史记录
        $remark = $request->get('remark');    //病史备注说明

        $updateData = array();
        if (!empty($telephone) || isset($telephone)) {
            $updateData['mobile'] = $telephone;
        }
        if (!empty($address) || isset($address)) {
            $updateData['address'] = $address;
        }
        if (!empty($height) || isset($height)) {
            $updateData['height'] = $height;
        }
        if (!empty($weight) || isset($weight)) {
            $updateData['weight'] = $weight;
        }
        if (!empty($physical) || isset($physical)) {
            $updateData['physical_fitness'] = $physical;
        }
        if (!empty($psychological) || isset($psychological)) {
            $updateData['psychological_quality'] = $psychological;
        }
        if (!empty($record) || isset($record)) {
            $physical_history = $record['physical'];
            $psychological_history = $record['psychological'];
            if (empty($physical_history)) {
                $physical_history = '';
            }
            if (empty($physical_history)) {
                $physical_history = '';
            }
            $history = $physical_history.'--'.$psychological_history;
            $updateData['medical_history'] = $history;
        }
        if (!empty($remark) || isset($remark)) {
            $updateData['ill_remark'] = $remark;
        }

        $rspObj = NewStudent::where('exam_code', $code)
            ->update($updateData);
        $custodians = $request->get('custodians');
        if (count($custodians) > 0) {
            //删除原来的监护人
            $rspObj = Custodians::where('exam_code',$code)->delete();
             //添加新的监护人
            foreach ($custodians as $item) {
                // 拼装新增数据数组
                $insertData = [
                    'exam_code' => $code,
                    'custodian_title' => $item['title'],
                    'custodian_name' => $item['name'],
                    'custodian_mobile' => $item['mobile'],
                ];
                $rspObj = Custodians::updateOrCreate(['exam_code' => $code,'custodian_title' => $item['title']], $insertData);
            }
        }
        return $rspObj;
    }

    /***
     *  数据库更新头像路径
     * @param $code
     * @param $originPath
     * @return mixed
     */
    private function handleUpdateAvatar($code, $originPath) {
        // 头像原图路径
        $data = [
            'avatar' => $originPath,
        ];
        $rspObj = NewStudent::where('exam_code', $code)->update($data);
        return $rspObj;
    }

    /***
     * 根据考试号获取学生基础信息
     * @param $code
     */
    private function getStudentInfo($code){
        $student = NewStudent::where('exam_code',$code)->first();
        return $student;
    }

    /***
     * 根据考试号获取学生监护人信息
     * @param $code
     */
    private function getStudentCustodians($code){
        $custodians = Custodians::where('exam_code',$code)->get();
        return $custodians;
    }


    ///////////////////////////////////////////////////////////////////
    /// 功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 验证文件是否上传成功
     *
     * @param $url
     * @return bool
     */
    protected function checkFile($url)
    {
        // 验证文件已存在
        $exists = Storage::disk('public')->exists($url);
        if ($exists) {
            return true;
        }
        return false;
    }
    /**
     * 验证文件类型是否合法
     *
     * @param $objFile 文件对象
     * @return bool
     */
    protected function validFile($objFile)
    {
        // 合法文件类型
        $fileTypes = array('png', 'jpg', 'jpeg');
        if (in_array($objFile->getClientOriginalExtension(), $fileTypes)) {
            return true;
        }
        return false;
    }


    /***
     * 微信
     */
    /***
     * 根据$third_session从数据库取出sessionKey
     * @param $third_session
     */
    private function getSessionKey($third_session, $result) {
        if (Redis::exists($third_session)) {
            $session_key = Redis::get($third_session);
            $sessionArr = explode(' ',$session_key);
            if (count($sessionArr)==2){
                return $sessionArr[1];
            }else {
                $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                $result['errorMsg'] = 'thirdSession不正确或已过期';
                return $result;
            }
        }else {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = 'thirdSession不正确或已过期';
            return $result;
        }
    }

    /***
     * 关联用户
     * @param $union_id
     * @param $result
     * @return mixed
     */
    private function relateUser($union_id,$open_id,$code) {
        $insert_data = [
            'unionid' => $union_id,
            'openid' => $open_id,
            'exam_code' => $code,
        ];
        $rspObj = WeChatLogin::updateOrCreate(['unionid'=>$union_id],$insert_data);
        return $rspObj;
    }
}
